package com.avego.game.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import com.avego.game.BoardCoordinates;
import com.avego.game.Player;

@Aspect
public class LoggingAspect {

	public static String newline = System.getProperty("line.separator");


	@AfterReturning(pointcut = "execution(* com.avego.game.Board.addPlayer(..))", returning = "result")
	public void logAddPlayer(JoinPoint joinPoint, Object result) {

		Player player = (Player) joinPoint.getArgs()[0];
		BoardCoordinates coord = (BoardCoordinates) result;
		System.out.printf(
				"Player [%d] added to the game in the position: (%d,%d)"
						+ newline, player.getPlayerNumber(), coord.getRow(),
				coord.getColumn());
	}

	@Before("execution(* com.avego.game.Board.movePlayer(..))")
	public void logBeforeMovePlayer(JoinPoint joinPoint) {

		Player player = (Player) joinPoint.getArgs()[0];
		BoardCoordinates coord = (BoardCoordinates) joinPoint.getArgs()[1];

		System.out.printf("Player [%d] is going to move to position: (%d,%d)"
				+ newline, player.getPlayerNumber(), coord.getRow(),
				coord.getColumn());
	}


	@After("execution(* com.avego.game.Board.removePlayerFromBoard(..))")
	public void logPlayerRemoveFromBoard(JoinPoint joinPoint) {

		Player player = (Player) joinPoint.getArgs()[0];

		System.out.printf("Player [%d] is removed from board." + newline,
				player.getPlayerNumber());

	}

	@After("execution(* com.avego.game.Board.removePlayerFromGame(..))")
	public void logPlayerRemoveFromGame(JoinPoint joinPoint) {

		Player player = (Player) joinPoint.getArgs()[0];

		System.out.printf("Player [%d] is removed from game." + newline,
				player.getPlayerNumber());

	}

	@AfterReturning(pointcut = "execution(* com.avego.game.Referee.validatePlayerMove(..))", returning = "result")
	public void logValidatePlayerMovement(JoinPoint joinPoint, Object result) {

		Player player = (Player) joinPoint.getArgs()[0];
		boolean value = (Boolean) result;
		
		if (!value)

			System.out.printf("Invalid movement from Player [%d]." + newline,
					player.getPlayerNumber());
	}
	
	@AfterReturning(pointcut = "execution(* com.avego.game.Referee.canPlayerReturnToGame(..))", returning = "result")
	public void logCanPlayerBackToGame(JoinPoint joinPoint, Object result) {

		Player player = (Player) joinPoint.getArgs()[0];
		boolean value = (Boolean) result;

		if (value)

			System.out.printf("Player [%d] is returning to game." + newline,
					player.getPlayerNumber());
		else
			System.out.printf("Player [%d] is out of to game." + newline,
					player.getPlayerNumber());
	}
	
	
}
